from django.dispatch import receiver
from django.contrib.auth import user_logged_in, user_logged_out, user_login_failed, get_user_model
from django.db import transaction

from auditlog.middleware import get_current_request
from auditlog.models import LoginEvent


def get_remote_addr(request=None):
    if request is None:
        request = get_current_request()
    remote_addr = request.META.get('REMOTE_ADDR')
    if request.META.get('HTTP_X_FORWARDED_FOR'):
        remote_addr = request.META.get('HTTP_X_FORWARDED_FOR').split(',')[0]
    return remote_addr


@receiver(user_logged_in, dispatch_uid='user_logged_in_event')
def user_logged_in_event(sender, request, user, **kwargs):
    try:
        with transaction.atomic():
            LoginEvent.objects.create(**{
                'action': LoginEvent.LOGIN,
                'username': getattr(user, user.USERNAME_FIELD),
                'user_id': getattr(user, 'id', None),
                'remote_ip': get_remote_addr(request)
            })
    except:
        ...


@receiver(user_logged_out, dispatch_uid='user_logged_out_event')
def user_logged_out_event(sender, request, user, **kwargs):
    try:
        with transaction.atomic():
            LoginEvent.objects.create(**{
                'action': LoginEvent.LOGOUT,
                'username': getattr(user, user.USERNAME_FIELD),
                'user_id': getattr(user, 'id', None),
                'remote_ip': get_remote_addr(request)
            })
    except:
        ...


@receiver(user_login_failed, dispatch_uid='user_login_failed_event')
def user_login_failed_event(sender, credentials, **kwargs):
    try:
        with transaction.atomic():
            user_model = get_user_model()
            LoginEvent.objects.create(**{
                'action': LoginEvent.FAILED,
                'username': credentials[user_model.USERNAME_FIELD],
                'remote_ip': get_remote_addr()
            })
    except:
        ...
